import {
  createContext,
  FC,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useReducer,
} from "react";
import { FormInstance } from "antd/es/form/Form";
import { CompProps } from "../../types/comp";
import { useMutation } from "@tanstack/react-query";
import request from "../../utils/request";
import { Form } from "antd";
import { UseMutationResult } from "@tanstack/react-query/src/types";
import { get, has, isArray } from "lodash";

type PaginationProps = {
  current: number;
  pageSize: number;
  total: number;
};

export type ContextVal = {
  pagination: PaginationProps;
  setPagination: (pagination: Partial<PaginationProps>) => void;
  getSearchFilter?: () => void;
  clearInfo: () => void;
  query?: UseMutationResult;
  searchForm?: FormInstance;
};
const Context = createContext<ContextVal>({
  pagination: {
    current: 1,
    pageSize: 10,
    total: 0,
  },
  clearInfo: () => {},
  setPagination: () => {},
});

export type SearchPageProviderProps = {
  src: string;
  searchForm?: ContextVal["searchForm"];
  uploadData?: (data: any[]) => void;
  onMount?: (v: ContextVal) => void;
  defaultPageSize: number;
  searchFormat?: (data: any) => any;
  defaultFilters?: Record<any, any>;
  onSearchHandle?: (params: any) => void;
  noSearch?: any;
  queryMutationParams?: any
} & CompProps;

export const SearchPageProvider: FC<SearchPageProviderProps> = ({
  children,
  src,
  searchForm,
  onMount,
  uploadData,
  defaultPageSize,
  searchFormat,
  onSearchHandle,
  defaultFilters,
                                                                  queryMutationParams,
  noSearch,
}) => {
  const [form] = Form.useForm(searchForm);
  const getInitPagination = useCallback(
    () => ({
      current: 1,
      pageSize: defaultPageSize,
      total: 0,
    }),
    []
  );
  const [pagination, setPagination] = useReducer<
    (prev: PaginationProps, action: Partial<PaginationProps>) => PaginationProps
  >(
    (prev, newAction) => ({
      ...prev,
      ...newAction,
    }),
    getInitPagination()
  );

  const formatData = (data: any) => {
    const result = { ...defaultFilters, ...data };
    if (has(data, "time") && isArray(data?.time)) {
      result.start_time = result.time[0].format("YYYY-MM-DD");
      result.end_time = result.time[1].format("YYYY-MM-DD");
      Reflect.deleteProperty(result, "time");
    }
    return searchFormat ? searchFormat(result) : result;
  };

  const query = useMutation({
    ...queryMutationParams,
    mutationFn: async () => {
      const searchParams = formatData(form.getFieldsValue());
      const res = await request(src, {
        method: "POST",
        params: pagination,
        isCustomData: true,
        data: searchParams,
      });
      onSearchHandle?.(searchParams);
      setPagination({
        total: get(res, "total", 0),
      });
      uploadData?.(isArray(res.list) ? res.list : []);
      return res?.list;
    },

  });

  useEffect(() => {
    if (!noSearch) query.mutate();
  }, []);
  const value = useMemo(
    () => ({
      searchForm: form,
      pagination,
      setPagination,
      clearInfo: () => {
        setPagination(getInitPagination());
        uploadData?.([])
      },
      getSearchFilter: () => formatData(form.getFieldsValue()),
      query,
    }),
    [pagination, setPagination, query, form, formatData, getInitPagination, uploadData]
  );
  useEffect(() => {
    onMount?.(value);
  }, [value]);

  return <Context.Provider value={value}>{children}</Context.Provider>;
};

export const useSearchPageContext = () => useContext(Context);

export default Context;
